<template>
  <div :style="editorStyles">
    <div ref="monacoEditorRef" class="monaco-editor"></div>
  </div>
</template>
<script setup lang="ts">
import * as monaco from "monaco-editor";
import { editor } from "monaco-editor";
import { computed, defineProps, onMounted, ref, watch } from "vue";

const props = defineProps({
  width: {
    type: [String, Number],
    default: "100%",
  },
  height: {
    type: [String, Number],
    default: "100%",
  },
  database: {
    type: String,
    default: "",
  },
  onEditAction: {
    type: Function, // 自动补全接口方法
    required: true,
  },
});
const emit = defineEmits(["onQuery"]);

const editorStyles = computed(() => {
  return {
    width: typeof props.width === "number" ? `${props.width}px` : props.width,
    height: typeof props.height === "number" ? `${props.height}px` : props.height,
  };
});

const monacoEditorRef = ref<HTMLElement | null>(null);
const editorOptions: editor.IStandaloneEditorConstructionOptions = {
  value: "",
  language: "sql",
  theme: "vs-light",
  fontSize: 16,
  lineHeight: 24,
  trimAutoWhitespace: false,
  automaticLayout: true, // 自动布局
  foldingStrategy: "indentation", // 代码可分小段折叠
  autoClosingBrackets: "always", // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
  autoClosingDelete: "always", // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
  autoClosingQuotes: "always", // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
  autoIndent: "none", // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
  comments: {
    ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
    insertSpace: true, // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
  }, // 注释配置
  //
  // cursorBlinking: "Solid", // 光标动画样式
  // cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
  // cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
  // cursorSurroundingLinesStyle: "all", // "default" | "all" 光标环绕样式
  // cursorWidth: 1, // <=25 光标宽度
  minimap: {
    enabled: true, // 是否启用预览图
    maxColumn: 80, //缩略图列数（控制宽度）
    showSlider: "always",
  },
  overviewRulerBorder: false, // 是否应围绕概览标尺绘制边框
  readOnly: false,
  folding: true, // 是否启用代码折叠
  scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后
  renderLineHighlight: "all", // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
  contextmenu: true,
  mouseWheelZoom: true, //鼠标缩放字体大小
  snippetSuggestions: "bottom",
  scrollbar: {
    verticalScrollbarSize: 0,
    horizontalScrollbarSize: 8,
    handleMouseWheel: true, //
    alwaysConsumeMouseWheel: false, //不阻止滚动事件，让外层还能滚动
  },
};

const focus = ref(false);

async function initEditor() {
  if (monacoEditorRef.value) {
    const instance = editor.create(monacoEditorRef.value, editorOptions);

    // 注册右键菜单操作
    instance.addAction({
      id: "execute-selected-sql",
      label: "执行选择的 SQL",
      keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter], // 可选：快捷键
      contextMenuGroupId: "navigation", // 定义分组
      contextMenuOrder: 1, // 定义菜单中的显示顺序
      run: () => {
        const rangeText = instance
          .getModel()
          ?.getValueInRange(instance.getSelection() as any);
        let sql = rangeText;
        if (!sql) {
          sql = instance.getValue();
        }
        console.log("ctrl+enter 去执行sql吧, database:", props.database, ", sql:", sql);

        emit("onQuery", { database: props.database, sql });
      },
    });

    // 添加鼠标悬停监听
    instance.onMouseMove((e) => {
      if (e.target && e.target.position) {
        const position = e.target.position;
        const model = instance.getModel();
        if (model) {
          const word = model.getWordAtPosition(position);
          if (word) {
            console.log("Hovered word:", word.word); // 打印悬停的单词
            // 可以在这里调用服务端接口或处理逻辑来获取悬停信息
          }
        }
      }
    });

    instance.onDidBlurEditorWidget(() => {
      // 你的逻辑
      console.log("onDidBlurEditorWidget");
      focus.value = false;
    });

    instance.onDidFocusEditorWidget(() => {
      console.log("onDidFocusEditorWidget");
      focus.value = true;
    });

    // 监听光标位置变化并触发自动提示接口
    instance.onDidChangeCursorPosition(async (event) => {
      const position = event.position;
      const model = instance.getModel();

      if (model) {
        const input = model.getValue(); // 获取当前编辑器内容
        const line = position.lineNumber;
        const col = position.column;

        if (props.database && input) {
          try {
            const completionItems = await props.onEditAction("complete", {
              database: props.database,
              input: input,
              line: line - 1,
              col: col - 1,
            });
            return {
              suggestions: completionItems.map((item) => ({
                ...item,
                label: item.label,
                kind: item.kind,
                insertText: item.insertText || item.label,
              })),
            };
          } catch (error) {
            console.error("获取自动提示失败:", error);
          }
        }
      }
    });

    // 添加自动补全提供者
    monaco.languages.registerCompletionItemProvider("sql", {
      triggerCharacters: [".", " "],
      provideCompletionItems: async (model, position) => {
        const curId = instance.getId();
        if (!focus.value) {
          console.log("current id:", curId, "is not focus");
          return;
        }
        const wordInfo = model.getWordUntilPosition(position);
        const range = new monaco.Range(
          position.lineNumber,
          wordInfo.startColumn,
          position.lineNumber,
          wordInfo.endColumn
        );

        const sql = instance.getValue();
        console.log("curId:", curId, "database:", props.database, "sql:", sql);

        let col = position.column;

        if (col > sql.length) {
          col = sql.length;
        }

        // 使用 props.onEditAction 接口动态获取补全内容
        try {
          const completionItems = await props.onEditAction("complete", {
            database: props.database,
            input: sql,
            line: position.lineNumber - 1,
            col: col - 1,
          });

          return {
            suggestions: completionItems.map((item) => ({
              ...item,
              label: item.label,
              kind: item.kind,
              insertText: item.insertText || item.label,
              range,
            })),
          };
        } catch (error) {
          console.error("获取补全内容失败:", error);
          return { suggestions: [] };
        }
      },
    });
  }
}

onMounted(() => {
  initEditor();
});

// 监听 props.database 的变化
watch(
  () => props.database, // 监听 props.database 的变化
  (newDatabase, oldDatabase) => {
    console.log("Database changed from", oldDatabase, "to", newDatabase);
    // 这里你可以执行任何操作，像更新编辑器中的数据库配置，或执行查询等
    // 比如：
  }
);
</script>

<style scoped lang="less">
.monaco-editor {
  width: 100%;
  height: 100%;
  border: 1px solid #e5e5e5;
}

.monaco-editor .monaco-hover {
  background-color: #f9f9f9 !important;
  border: 1px solid #ddd !important;
  font-size: 14px;
}
</style>
